package org.example.exampreparationtreasure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.exampreparationtreasure.common.IncorrectQuestionResultStatus;
import org.example.exampreparationtreasure.exception.IncorrectQuestionException;
import org.example.exampreparationtreasure.mapper.IncorrectQuestionRecordMapper;
import org.example.exampreparationtreasure.mapper.QuestionMapper;
import org.example.exampreparationtreasure.mapper.UserMapper;
import org.example.exampreparationtreasure.model.entity.Categories;
import org.example.exampreparationtreasure.model.entity.IncorrectQuestionRecord;
import org.example.exampreparationtreasure.model.entity.Question;
import org.example.exampreparationtreasure.model.entity.User;
import org.example.exampreparationtreasure.service.CategoryService;
import org.example.exampreparationtreasure.service.IncorrectQuestionRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class IncorrectQuestionRecordServiceImpl implements IncorrectQuestionRecordService {
    
    @Autowired
    private IncorrectQuestionRecordMapper incorrectQuestionRecordMapper;
    
    @Autowired
    private CategoryService categoryService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private QuestionMapper questionMapper;
    
    @Override
    public IPage<IncorrectQuestionRecord> getIncorrectQuestionsByCategory(
            Page<IncorrectQuestionRecord> page, Long userId, Long categoryId) {
        
        // 参数验证
        validatePageParams(page);
        validateUserId(userId);
        validateCategoryId(categoryId);
        
        try {
            return incorrectQuestionRecordMapper.selectIncorrectQuestionsByCategory(page, userId, categoryId);
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "查询分类错题记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public IPage<IncorrectQuestionRecord> getIncorrectQuestionsByCategoryWithSubcategories(
            Page<IncorrectQuestionRecord> page, Long userId, Long categoryId, boolean includeSubcategories) {
        
        // 参数验证
        validatePageParams(page);
        validateUserId(userId);
        validateCategoryId(categoryId);
        
        if (!includeSubcategories) {
            // 只查询当前分类
            return getIncorrectQuestionsByCategory(page, userId, categoryId);
        }
        
        try {
            // 获取当前分类及其所有子分类的ID列表
            List<Categories> allDescendants = categoryService.getAllDescendantsByParentId(categoryId);
            List<Long> categoryIds = allDescendants.stream()
                    .map(Categories::getCategoryId)
                    .collect(Collectors.toList());
            
            // 添加当前分类ID
            categoryIds.add(categoryId);
            
            return incorrectQuestionRecordMapper.selectIncorrectQuestionsByCategories(page, userId, categoryIds);
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "查询分类及子分类错题记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public IPage<IncorrectQuestionRecord> getAllIncorrectQuestionsByUser(
            Page<IncorrectQuestionRecord> page, Long userId) {
        
        // 参数验证
        validatePageParams(page);
        validateUserId(userId);
        
        try {
            QueryWrapper<IncorrectQuestionRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                       .orderByDesc("last_mistake_time");
            
            return incorrectQuestionRecordMapper.selectPage(page, queryWrapper);
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "查询用户错题记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean addIncorrectQuestion(Long userId, Long questionId, String mistakeReason) {
        // 参数验证
        validateUserId(userId);
        validateQuestionId(questionId);
        // 允许 mistakeReason 为 null
        if (mistakeReason != null) {
            validateMistakeReason(mistakeReason);
        }
        
        // 验证用户存在性
        validateUserExists(userId);
        
        try {
            // 获取题目信息以获得分类ID，同时验证题目是否存在
            Question question = questionMapper.selectById(questionId);
            if (question == null) {
                throw new IncorrectQuestionException(IncorrectQuestionResultStatus.QUESTION_NOT_EXISTS);
            }
            
            // 先查询是否已存在该错题记录
            QueryWrapper<IncorrectQuestionRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                       .eq("question_id", questionId);
            
            IncorrectQuestionRecord existingRecord = incorrectQuestionRecordMapper.selectOne(queryWrapper);
            
            if (existingRecord != null) {
                // 如果已存在，更新错误次数和最后错误时间
                existingRecord.setMistakeCount(existingRecord.getMistakeCount() + 1);
                existingRecord.setMistakeReason(mistakeReason);
                existingRecord.setLastMistakeTime(LocalDateTime.now());
                existingRecord.setUpdateTime(LocalDateTime.now());
                // 更新分类ID（防止题目分类发生变化）
                existingRecord.setCategoryId(question.getCategoryId());
                
                int result = incorrectQuestionRecordMapper.updateById(existingRecord);
                if (result <= 0) {
                    throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INCORRECT_QUESTION_UPDATE_FAILED);
                }
                return true;
            } else {
                // 如果不存在，创建新记录
                IncorrectQuestionRecord newRecord = new IncorrectQuestionRecord();
                newRecord.setUserId(userId);
                newRecord.setQuestionId(questionId);
                newRecord.setCategoryId(question.getCategoryId()); // 设置分类ID
                newRecord.setMistakeCount(1);
                newRecord.setMistakeReason(mistakeReason);
                newRecord.setFirstMistakeTime(LocalDateTime.now());
                newRecord.setLastMistakeTime(LocalDateTime.now());
                newRecord.setCreateTime(LocalDateTime.now());
                newRecord.setUpdateTime(LocalDateTime.now());
                
                int result = incorrectQuestionRecordMapper.insert(newRecord);
                if (result <= 0) {
                    throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INCORRECT_QUESTION_ADD_FAILED);
                }
                return true;
            }
        } catch (IncorrectQuestionException e) {
            throw e;
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "添加错题记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean removeIncorrectQuestion(Long userId, Long questionId) {
        // 参数验证
        validateUserId(userId);
        validateQuestionId(questionId);
        
        try {
            // 检查记录是否存在
            QueryWrapper<IncorrectQuestionRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                       .eq("question_id", questionId);
            
            IncorrectQuestionRecord existingRecord = incorrectQuestionRecordMapper.selectOne(queryWrapper);
            if (existingRecord == null) {
                throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INCORRECT_QUESTION_NOT_FOUND);
            }
            
            int result = incorrectQuestionRecordMapper.delete(queryWrapper);
            if (result <= 0) {
                throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INCORRECT_QUESTION_DELETE_FAILED);
            }
            return true;
        } catch (IncorrectQuestionException e) {
            throw e;
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "删除错题记录失败: " + e.getMessage());
        }
    }
    
    // 参数验证方法
    private void validatePageParams(Page<?> page) {
        if (page == null || page.getCurrent() <= 0 || page.getSize() <= 0) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_PAGE_PARAMS);
        }
    }
    
    private void validateUserId(Long userId) {
        if (userId == null || userId <= 0) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_USER_ID);
        }
    }
    
    private void validateQuestionId(Long questionId) {
        if (questionId == null || questionId <= 0) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_QUESTION_ID);
        }
    }
    
    private void validateCategoryId(Long categoryId) {
        if (categoryId == null || categoryId <= 0) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_CATEGORY_ID);
        }
    }
    
    private void validateMistakeReason(String mistakeReason) {
        if (!StringUtils.hasText(mistakeReason)) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_MISTAKE_REASON);
        }
        
        // 验证错误原因是否在允许的枚举值中
        String[] allowedReasons = {"概念错误", "计算错误", "审题错误"};
        boolean isValid = Arrays.stream(allowedReasons)
                .anyMatch(reason -> reason.equals(mistakeReason));
        
        if (!isValid) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.INVALID_MISTAKE_REASON, 
                    "错误原因必须是: " + String.join(", ", allowedReasons));
        }
    }
    
    private void validateUserExists(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.USER_NOT_EXISTS);
        }
    }
    
    
    @Override
    public IPage<IncorrectQuestionRecord> getIncorrectQuestionsByCategoryDirect(
            Page<IncorrectQuestionRecord> page, Long userId, Long categoryId) {
        
        // 参数验证
        validatePageParams(page);
        validateUserId(userId);
        validateCategoryId(categoryId);
        
        try {
            // 首先尝试直接查询（基于category_id字段）
            IPage<IncorrectQuestionRecord> result = incorrectQuestionRecordMapper.selectIncorrectQuestionsByCategory(page, userId, categoryId);
            
            // 如果直接查询没有结果，尝试联表查询（兜底方案）
            if (result.getRecords().isEmpty()) {
                System.out.println("直接查询无结果，尝试联表查询 - userId: " + userId + ", categoryId: " + categoryId);
                result = incorrectQuestionRecordMapper.selectIncorrectQuestionsByCategoryWithJoin(page, userId, categoryId);
                
                // 如果联表查询有结果，说明category_id字段可能为空，需要更新
                if (!result.getRecords().isEmpty()) {
                    System.out.println("联表查询找到 " + result.getRecords().size() + " 条记录，建议执行数据迁移脚本更新category_id字段");
                }
            }
            
            return result;
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "查询分类错题记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public int fixMissingCategoryIds() {
        try {
            // 查询所有 category_id 为空的记录
            QueryWrapper<IncorrectQuestionRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.isNull("category_id");
            
            List<IncorrectQuestionRecord> recordsWithoutCategoryId = incorrectQuestionRecordMapper.selectList(queryWrapper);
            
            int fixedCount = 0;
            for (IncorrectQuestionRecord record : recordsWithoutCategoryId) {
                // 根据 question_id 获取对应的分类ID
                Question question = questionMapper.selectById(record.getQuestionId());
                if (question != null && question.getCategoryId() != null) {
                    record.setCategoryId(question.getCategoryId());
                    record.setUpdateTime(LocalDateTime.now());
                    
                    int result = incorrectQuestionRecordMapper.updateById(record);
                    if (result > 0) {
                        fixedCount++;
                    }
                }
            }
            
            System.out.println("成功修复 " + fixedCount + " 条错题记录的 category_id 字段");
            return fixedCount;
            
        } catch (Exception e) {
            throw new IncorrectQuestionException(IncorrectQuestionResultStatus.DATABASE_OPERATION_FAILED, 
                    "修复 category_id 字段失败: " + e.getMessage());
        }
    }
}
